﻿#include "GraphVTKObjectPartMesh.h"
#include "RadiossVTKGraphActor.h"
#include "GraphDataSetCompomentManager.h"
#include "GraphVTKObjectHighlighting.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Kernel/FITKAppFramework/FITKRunTimeSetting.h"

#include "FITK_Component/FITKRadiossData/FITKRadiossNodesParts.h"
#include "FITK_Component/FITKRadiossData/FITKRadiossMeshModel.h"
#include "FITK_Component/FITKRadiossData/FITKRadiossCase.h"
#include "FITK_Interface/FITKInterfaceModel/FITKAbstractElement.h"
#include "FITK_Interface/FITKInterfaceModel/FITKUnstructuredMesh.h"
#include "FITK_Interface/FITKInterfaceMesh/FITKMeshFeatureVTK.h"
#include "FITK_Interface/FITKVTKAlgorithm/FITKSurfaceFilter.h"
#include "FITK_Interface/FITKVTKAlgorithm/FITKHighOrderCellFilter.h"
#include "FITK_Interface/FITKVTKAlgorithm/FITKShellFeatureEdges.h"
#include "FITK_Kernel/FITKCore/FITKVec3D.h"

#include <QVector>
#include <vtkUnstructuredGrid.h>
#include <vtkDataSetSurfaceFilter.h>
#include <vtkCellData.h>
#include <vtkProperty.h>
#include <vtkUnsignedCharArray.h>
#include <vtkPointData.h>
#include <vtkMapper.h>
namespace Exchange {
    GraphVTKObjectPartMesh::GraphVTKObjectPartMesh(Radioss::FITKRadiossPart* dataObj) :
        GraphVTKObjectModelBase(dataObj)
    {
        if (dataObj == nullptr) return;

        init();
        initActor();
    }
    GraphVTKObjectPartMesh::~GraphVTKObjectPartMesh()
    {
        deleteVtkObj(_meshCellData);
        deleteVtkObj(_meshVertexData);
        deleteVtkObj(_meshSurfPointData);
        if (_meshFeature != nullptr) {
            delete _meshFeature;
            _meshFeature = nullptr;
        }
    }
    void GraphVTKObjectPartMesh::init()
    {
        Radioss::FITKRadiossPart* part = dynamic_cast<Radioss::FITKRadiossPart*>(_dataObj);
        if (part == nullptr) return;

        _meshCellData = vtkUnstructuredGrid::New();
        _meshCellData->SetPoints(vtkSmartPointer<vtkPoints>::New());

        _meshVertexData = vtkUnstructuredGrid::New();
        _meshVertexData->SetPoints(vtkSmartPointer<vtkPoints>::New());

        _meshSurfPointData = vtkUnstructuredGrid::New();
        _meshSurfPointData->SetPoints(vtkSmartPointer<vtkPoints>::New());

        // 初始化 _meshFeature
        createCellGrid();

        _meshFeature = new Interface::FITKMeshFeatureVTK(_meshCellData);
        _meshFeature->getFeatureEdgeFilter()->FeatureEdgesOff();
        _meshFeature->getFeatureEdgeFilter()->BoundaryEdgesOff();
        _meshFeature->setSurfEdgesEnable(false);
        _meshFeature->update();

        createVertexGrid();
        //创建表面节点
        createSurfPointGrid();
    }

    void GraphVTKObjectPartMesh::initActor()
    {
        Radioss::FITKRadiossPart* part = dynamic_cast<Radioss::FITKRadiossPart*>(_dataObj);
        if (part == nullptr) return;
        QColor color = part->getColor();
        this->setRenderLayer(0);

        // 创建节点演员
        _meshVertexActor = RadiossVTKGraphActor::New();
        _meshVertexActor->SetPickable(false);
        _meshVertexActor->setGraphObject(this);
        _meshVertexActor->setInputDataObject(_meshVertexData);
        _meshVertexActor->GetProperty()->SetPointSize(5);
        _meshVertexActor->GetProperty()->SetOpacity(1);
        _meshVertexActor->setRelativeCoincidentTopologyPolygonOffsetParameters(GraphVTKCommons::_mesh3DGraphOffset, 1);
        addActor(_meshVertexActor);

        // 创建表面节点演员
        _meshSurfNodeActor = RadiossVTKGraphActor::New();
        _meshSurfNodeActor->SetPickable(false);
        _meshSurfNodeActor->setGraphObject(this);
        _meshSurfNodeActor->GetProperty()->SetPointSize(0.5);
        _meshSurfNodeActor->setInputDataObject(_meshSurfPointData);
        _meshSurfNodeActor->setRelativeCoincidentTopologyPolygonOffsetParameters(GraphVTKCommons::_mesh3DGraphOffset, 1);
        addActor(_meshSurfNodeActor);

        // 创建单元演员
        _meshCellActor = RadiossVTKGraphActor::New();
        _meshCellActor->SetPickable(false);
        _meshCellActor->setGraphObject(this);
        _meshCellActor->GetProperty()->SetLineWidth(2);
        _meshSurfNodeActor->GetProperty()->SetRepresentation(VTK_SURFACE);
        _meshCellActor->GetProperty()->SetColor(color.redF(), color.greenF(), color.blueF());
        _meshCellActor->GetProperty()->SetOpacity(1);
        _meshCellActor->setInputDataObject(_meshCellData);
        _meshCellActor->setRelativeCoincidentTopologyPolygonOffsetParameters(GraphVTKCommons::_mesh3DGraphOffset,1);
        addActor(_meshCellActor);
        setLightPropertiesForSurface(_meshCellActor);

        // 创建表面单元演员
        _meshSurfCellActor = RadiossVTKGraphActor::New();
        _meshSurfCellActor->SetPickable(false);
        _meshSurfCellActor->setGraphObject(this);
        _meshSurfCellActor->GetProperty()->SetLineWidth(2);
        _meshSurfNodeActor->GetProperty()->SetRepresentation(VTK_SURFACE);
        _meshSurfCellActor->GetProperty()->SetColor(color.redF(), color.greenF(), color.blueF());
        _meshSurfCellActor->GetProperty()->SetOpacity(1);
        _meshSurfCellActor->setInputConnection(_meshFeature->getSurfaceFilter()->GetOutputPort());
        _meshSurfCellActor->setRelativeCoincidentTopologyPolygonOffsetParameters(GraphVTKCommons::_mesh3DGraphOffset,1);
        addActor(_meshSurfCellActor);
        setLightPropertiesForSurface(_meshSurfCellActor);

        m_graphObjHighlight->setModelInputConnection(_meshFeature->getSurfaceFilter()->GetOutputPort());
        m_graphObjHighlight->setActorType(-1);
    }
    vtkDataSet* GraphVTKObjectPartMesh::getMesh(GraphVTKCommons::ShapePickMode pickType)
    {
        switch (pickType) {
        case GraphVTKCommons::ShapePickMode::PickMeshVertex:
            return _meshVertexData;
        case GraphVTKCommons::ShapePickMode::PickMeshCell:
            return _meshCellData;
        case GraphVTKCommons::ShapePickMode::PickMeshVertexSurf:
            return _meshSurfPointData;
        case GraphVTKCommons::ShapePickMode::PickMeshCellSurf:
            if (_meshFeature == nullptr || _meshFeature->getSurfaceFilter() == nullptr) {
                return nullptr;
            }
            return _meshFeature->getSurfaceFilter()->GetOutput();
        }
        return nullptr;
    }
    Interface::FITKMeshFeatureVTK* GraphVTKObjectPartMesh::getMeshFeature() const
    {
        return _meshFeature;
    }


    bool GraphVTKObjectPartMesh::updateGraphData()
    {
        _meshFeature->update();
        //创建节点
        createVertexGrid();
        //创建表面节点
        createSurfPointGrid();
        //创建单元
        createCellGrid();

        return true;
    }
    void GraphVTKObjectPartMesh::createCellGrid()
    {
        Radioss::FITKRadiossPart* part = dynamic_cast<Radioss::FITKRadiossPart*>(_dataObj);
        if (part == nullptr) return;
        //清空单元数据
        if (_meshCellData == nullptr || _meshCellData->GetPoints() == nullptr) {
            return;
        }
        Radioss::FITKRadiossCase* radiossCase = FITKAPP->getGlobalData()->getPhysicsData<Radioss::FITKRadiossCase>();
        if (!radiossCase) return;

        Radioss::FITKRadiossMeshModel* radiossMeshModel = radiossCase->getMeshModel();
        if (!radiossMeshModel) return;

        Radioss::FITKRadiossNodes* radiossNodes = radiossMeshModel->getNodes();
        if (!radiossNodes) return;

        _meshCellData->Reset();
        // 创建新的点和单元数据
        vtkSmartPointer<vtkUnstructuredGrid> grid = vtkSmartPointer<vtkUnstructuredGrid>::New();
        vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
        grid->SetPoints(points);

        // 单元ID存储数组
        vtkSmartPointer<vtkIntArray> cellID = vtkSmartPointer<vtkIntArray>::New();
        cellID->SetName(GraphVTKCommons::_dataCellIDArratName.toUtf8().constData());
        cellID->SetNumberOfComponents(1);
        grid->GetCellData()->AddArray(cellID);

        QList<int> partNodes = part->getAllNodeIDs();
        //节点填充
        QHash<int, int> pointId_vtkId = {};
        for (int partNode : partNodes) {
            Core::FITKNode* node = radiossNodes->getNodeByID(partNode);
            if (node == nullptr) continue;
            double point[3] = { 0,0,0 };
            node->getCoor(point);
            //创建单元
            int pointId = points->InsertNextPoint(point);
            pointId_vtkId.insert(node->getNodeID(), pointId);
        }

        for (int i = 0; i < part->getElementCount(); i++) {
            Interface::FITKAbstractElement* element = part->getElementAt(i);
            if (element == nullptr) continue;
            vtkSmartPointer<vtkIdList> cell = vtkSmartPointer<vtkIdList>::New();
            for (int nodeId : element->getAllNodes()) {
                int iPt = pointId_vtkId.value(nodeId);
                cell->InsertNextId(iPt);

            }

            int cellId = -1;
            switch (element->getEleType()) {
            case Interface::FITKModelEnum::EleNone: break;
            case Interface::FITKModelEnum::Line2:cellId = grid->InsertNextCell(VTK_LINE, cell); break;
            case Interface::FITKModelEnum::Line3:cellId = grid->InsertNextCell(VTK_QUADRATIC_EDGE, cell); break;
            case Interface::FITKModelEnum::Tri3:cellId = grid->InsertNextCell(VTK_TRIANGLE, cell); break;
            case Interface::FITKModelEnum::Tri6:cellId = grid->InsertNextCell(VTK_QUADRATIC_TRIANGLE, cell); break;
            case Interface::FITKModelEnum::Quad4:cellId = grid->InsertNextCell(VTK_QUAD, cell); break;
            case Interface::FITKModelEnum::Quad8:cellId = grid->InsertNextCell(VTK_QUADRATIC_QUAD, cell); break;
            case Interface::FITKModelEnum::Tet4:cellId = grid->InsertNextCell(VTK_TETRA, cell); break;
            case Interface::FITKModelEnum::Tet10: cellId = grid->InsertNextCell(VTK_QUADRATIC_TETRA, cell); break;
            case Interface::FITKModelEnum::Wedge6:cellId = grid->InsertNextCell(VTK_WEDGE, cell); break;
            case Interface::FITKModelEnum::Hex8:cellId = grid->InsertNextCell(VTK_HEXAHEDRON, cell); break;
            case Interface::FITKModelEnum::Hex20: cellId = grid->InsertNextCell(VTK_QUADRATIC_HEXAHEDRON, cell); break;
            case Interface::FITKModelEnum::Polygon: cellId = grid->InsertNextCell(VTK_POLYGON, cell); break;
            }
            if (cellId != -1) {
                cellID->InsertNextValue(element->getEleID());

            }
        }
        _meshCellData->DeepCopy(grid);
    }
    void GraphVTKObjectPartMesh::createVertexGrid()
    {
        Radioss::FITKRadiossPart* part = dynamic_cast<Radioss::FITKRadiossPart*>(_dataObj);
        if (part == nullptr) return;

        Radioss::FITKRadiossCase* radiossCase = FITKAPP->getGlobalData()->getPhysicsData<Radioss::FITKRadiossCase>();
        if (!radiossCase) return;

        Radioss::FITKRadiossMeshModel* radiossMeshModel = radiossCase->getMeshModel();
        if (!radiossMeshModel) return;

        Radioss::FITKRadiossNodes* radiossNodes = radiossMeshModel->getNodes();
        if (!radiossNodes) return;

        // 清空现有数据
        if (_meshVertexData == nullptr || _meshVertexData->GetPoints() == nullptr) {
            return;
        }
        _meshVertexData->Reset();

        // 创建新的点和单元数据
        vtkSmartPointer<vtkUnstructuredGrid> grid = vtkSmartPointer<vtkUnstructuredGrid>::New();
        vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();
        grid->SetPoints(points);

        // 节点ID存储数组
        vtkSmartPointer<vtkIntArray> pointIDArray = vtkSmartPointer<vtkIntArray>::New();
        pointIDArray->SetName(GraphVTKCommons::_dataPointIDArratName.toUtf8().constData());
        pointIDArray->SetNumberOfComponents(1);
        grid->GetCellData()->AddArray(pointIDArray);

        QList<int> partNodes = part->getAllNodeIDs();
        for (int partNode : partNodes)
        {
            Core::FITKNode* node = radiossNodes->getNodeByID(partNode);
            if (node == nullptr) continue;
            double point[3] = { 0,0,0 };
            node->getCoor(point);
            //创建单元
            vtkSmartPointer<vtkIdList>cell = vtkSmartPointer<vtkIdList>::New();
            int pointId = points->InsertNextPoint(point);
            cell->InsertNextId(pointId);
            grid->InsertNextCell(VTKCellType::VTK_VERTEX, cell);
            pointIDArray->InsertNextValue(node->getNodeID());
        }
        _meshVertexData->DeepCopy(grid);
    }
    void GraphVTKObjectPartMesh::createSurfPointGrid()
    {
        //清空单元数据
        if (_meshSurfPointData == nullptr || _meshFeature == nullptr || _meshFeature->getSurfaceFilter() == nullptr) {
            return;
        }
        // 创建表面节点数据
        vtkDataSet* surfData = _meshFeature->getSurfaceFilter()->GetOutput();
        vtkPoints* surfPoints = _meshSurfPointData->GetPoints();
        if (surfData == nullptr || surfPoints == nullptr) {
            return;
        }
        //初始化数据
        _meshSurfPointData->Reset();
        _meshSurfPointData->GetPointData()->Reset();
        _meshSurfPointData->GetCellData()->Reset();
        surfPoints->Reset();

        for (int i = 0; i < surfData->GetNumberOfPoints(); i++) {
            double node[3] = { 0, 0, 0 };
            node[0] = surfData->GetPoint(i)[0];
            node[1] = surfData->GetPoint(i)[1];
            node[2] = surfData->GetPoint(i)[2];

            vtkSmartPointer<vtkIdList> cell = vtkSmartPointer<vtkIdList>::New();
            int pointId = surfPoints->InsertNextPoint(node);
            cell->InsertNextId(pointId);
            _meshSurfPointData->InsertNextCell(VTKCellType::VTK_VERTEX, cell);
        }
    }
    void GraphVTKObjectPartMesh::update(bool forceUpdate)
    {
        //更新可见
        updateVisibility();
        //判断是否需要刷新数据
        if (forceUpdate == false)
        {
            return;
        }
        updateGraphData();
    }
    void GraphVTKObjectPartMesh::updateVisibility()
    {
        if (_meshCellActor == nullptr || _meshVertexActor == nullptr) return;

        //获取运行时设置
        AppFrame::FITKRunTimeSetting* runSetting = FITKAPP->getGlobalData()->getRunTimeSetting();

        //获取点显示状态
        bool pointVisible = true;
        bool lineVisible = true;
        bool partVisible = true;
        partVisible = runSetting->getValue("Part").toBool();
        lineVisible = runSetting->getValue("MeshLine").toBool();
        pointVisible = runSetting->getValue("MeshPoint").toBool();
        if (partVisible == false && lineVisible == true)
        {
            _meshCellActor->SetVisibility(lineVisible);
            _meshCellActor->GetProperty()->SetRepresentation(VTK_WIREFRAME);
            _meshCellActor->GetProperty()->SetEdgeVisibility(lineVisible);

            _meshSurfCellActor->SetVisibility(lineVisible);
            _meshSurfCellActor->GetProperty()->SetRepresentation(VTK_WIREFRAME);
            _meshSurfCellActor->GetProperty()->SetEdgeVisibility(lineVisible);
        }
        else {
            _meshCellActor->SetVisibility(partVisible);
            _meshCellActor->GetProperty()->SetRepresentation(VTK_SURFACE);
            _meshCellActor->GetProperty()->SetEdgeVisibility(lineVisible);

            _meshSurfCellActor->SetVisibility(partVisible);
            _meshSurfCellActor->GetProperty()->SetRepresentation(VTK_SURFACE);
            _meshSurfCellActor->GetProperty()->SetEdgeVisibility(lineVisible);
        }
        _meshVertexActor->SetVisibility(pointVisible);

    }

    void GraphVTKObjectPartMesh::updateModelColor(QColor color)
    {
        // 检查对象是否有效
        Radioss::FITKRadiossPart* part = dynamic_cast<Radioss::FITKRadiossPart*>(_dataObj);
        if (part == nullptr) return;
        part->setColor(color);
        // 更新单元演员颜色
        if (_meshCellActor != nullptr) {
            _meshCellActor->GetProperty()->SetColor(color.redF(), color.greenF(), color.blueF());
            _meshCellActor->GetProperty()->SetOpacity(color.alphaF());
        }
        if (_meshSurfCellActor != nullptr) {
            _meshSurfCellActor->GetProperty()->SetColor(color.redF(), color.greenF(), color.blueF());
            _meshSurfCellActor->GetProperty()->SetOpacity(color.alphaF());
        }
    }
    void GraphVTKObjectPartMesh::updatePointSize(int size)
    {
        _meshVertexActor->GetProperty()->SetPointSize(size);
    }
    void GraphVTKObjectPartMesh::updateLineWidth(int width)
    {
        if (_meshCellActor) {
            _meshCellActor->GetProperty()->SetLineWidth(width);
        }
        if (_meshSurfCellActor) {
            _meshSurfCellActor->GetProperty()->SetLineWidth(width);
        }
    }
    void GraphVTKObjectPartMesh::updateOpacity(double opacity)
    {
        if (_meshCellActor) {
            _meshCellActor->GetProperty()->SetOpacity(opacity);
        }
        if (_meshSurfCellActor) {
            _meshSurfCellActor->GetProperty()->SetOpacity(opacity);
        }
    }
    void GraphVTKObjectPartMesh::updateRepresentation(int arg)
    {
        if (_meshCellActor) {
            _meshCellActor->GetProperty()->SetRepresentation(arg);
        }
        if (_meshSurfCellActor) {
            _meshSurfCellActor->GetProperty()->SetRepresentation(arg);
        }
    }
    void GraphVTKObjectPartMesh::setVisible(bool visibility)
    {
        if(_meshVertexActor)
            _meshVertexActor->SetVisibility(visibility);
        if(_meshSurfNodeActor)
            _meshSurfNodeActor->SetVisibility(visibility);
        if (_meshCellActor)
        {
            _meshCellActor->SetVisibility(visibility);
            _meshCellActor->GetProperty()->SetEdgeVisibility(visibility);
        }
        if (_meshSurfCellActor)
        {
            _meshSurfCellActor->SetVisibility(visibility);
            _meshSurfCellActor->GetProperty()->SetEdgeVisibility(visibility);
        }
        _isVisible = visibility;
    }
    void GraphVTKObjectPartMesh::setCellVisible(bool visibility)
    {
        //获取运行时设置
        AppFrame::FITKRunTimeSetting* runSetting = FITKAPP->getGlobalData()->getRunTimeSetting();
        bool lineVisible = runSetting->getValue("MeshLine").toBool();

        if (_meshCellActor) {
            if (lineVisible == true) {
                if (visibility == true)
                {
                    _meshCellActor->GetProperty()->SetRepresentation(VTK_SURFACE);
                    _meshSurfCellActor->GetProperty()->SetRepresentation(VTK_SURFACE);
                }
                else {
                    _meshCellActor->GetProperty()->SetRepresentation(VTK_WIREFRAME);
                    _meshSurfCellActor->GetProperty()->SetRepresentation(VTK_WIREFRAME);
                }
                _meshCellActor->GetProperty()->SetEdgeVisibility(lineVisible);
                _meshCellActor->SetVisibility(lineVisible || visibility);
                _meshSurfCellActor->GetProperty()->SetEdgeVisibility(lineVisible);
                _meshSurfCellActor->SetVisibility(lineVisible || visibility);
            }
            else {
                _meshCellActor->GetProperty()->SetRepresentation(VTK_SURFACE);
                _meshCellActor->GetProperty()->SetEdgeVisibility(lineVisible);
                _meshCellActor->SetVisibility(visibility);
                _meshSurfCellActor->GetProperty()->SetRepresentation(VTK_SURFACE);
                _meshSurfCellActor->GetProperty()->SetEdgeVisibility(lineVisible);
                _meshSurfCellActor->SetVisibility(visibility);
            }
        }
    }
    void GraphVTKObjectPartMesh::setPointVisibility(bool visibility)
    {
        if (_meshVertexActor) {
            _meshVertexActor->SetVisibility(visibility);
        }
        if (_meshSurfNodeActor) {
            _meshSurfNodeActor->SetVisibility(visibility);
        }
    }
    void GraphVTKObjectPartMesh::setLineVisibility(bool visibility)
    {
        AppFrame::FITKRunTimeSetting* runSetting = FITKAPP->getGlobalData()->getRunTimeSetting();
        bool partVisible = runSetting->getValue("Part").toBool();
        if (_meshCellActor) {
            if (partVisible == true)
            {
                _meshCellActor->GetProperty()->SetEdgeVisibility(visibility);
                _meshCellActor->GetProperty()->SetRepresentation(VTK_SURFACE);
                _meshCellActor->SetVisibility(partVisible);
                _meshSurfCellActor->GetProperty()->SetEdgeVisibility(visibility);
                _meshSurfCellActor->GetProperty()->SetRepresentation(VTK_SURFACE);
                _meshSurfCellActor->SetVisibility(partVisible);
                
            }
            else {
                _meshCellActor->GetProperty()->SetEdgeVisibility(visibility);
                _meshCellActor->GetProperty()->SetRepresentation(VTK_WIREFRAME);
                _meshCellActor->SetVisibility(partVisible || visibility);
                _meshSurfCellActor->GetProperty()->SetEdgeVisibility(visibility);
                _meshSurfCellActor->GetProperty()->SetRepresentation(VTK_WIREFRAME);
                _meshSurfCellActor->SetVisibility(partVisible || visibility);
            }
        }
    }
    void GraphVTKObjectPartMesh::setPickMode(GraphVTKCommons::ShapePickMode mode)
    {
        auto setActorPickable = [=](RadiossVTKGraphActor* fActor, bool isOn) {
            if (fActor) {
                fActor->SetPickable(isOn);
            }
            };

        switch (mode) {
        case GraphVTKCommons::PickMeshVertex:
            setActorPickable(_meshVertexActor, true);
            setActorPickable(_meshCellActor, false);
            setActorPickable(_meshSurfCellActor, false);
            setActorPickable(_meshSurfNodeActor, false);
            break;
        case GraphVTKCommons::PickMeshCell:
            setActorPickable(_meshVertexActor, false);
            setActorPickable(_meshCellActor, true);
            setActorPickable(_meshSurfCellActor, false);
            setActorPickable(_meshSurfNodeActor, false);
            break;
        case GraphVTKCommons::PickMeshCellSurf:
            setActorPickable(_meshVertexActor, false);
            setActorPickable(_meshCellActor, false);
            setActorPickable(_meshSurfCellActor, true);
            setActorPickable(_meshSurfNodeActor, false);
            break;
        case GraphVTKCommons::PickMeshVertexSurf:
            setActorPickable(_meshVertexActor, false);
            setActorPickable(_meshCellActor, false);
            setActorPickable(_meshSurfCellActor, false);
            setActorPickable(_meshSurfNodeActor, true);
            break;
        default:
            setActorPickable(_meshVertexActor, false);
            setActorPickable(_meshCellActor, false);
            setActorPickable(_meshSurfCellActor, false);
            setActorPickable(_meshSurfNodeActor, false);
            break;
        }

        //记录拾取类型
        GraphVTKObject3D::setPickMode(mode);
    }
    int GraphVTKObjectPartMesh::getShapeIdByVTKCellId(int vtkCellId, GraphVTKCommons::ShapePickMode pickType, QVariant otherInfo)
    {
        int shapeID = -1;
        switch (pickType) {
        case Exchange::GraphVTKCommons::ShapePickMode::PickMeshVertex: {
            if (_meshVertexData == nullptr) {
                return shapeID;
            }
            //获取点可视化数据存储的点形状id与点vtkid映射数组
            vtkIntArray* shapeIdArray = vtkIntArray::SafeDownCast(
                _meshVertexData->GetCellData()->GetArray(GraphVTKCommons::_dataPointIDArratName.toUtf8().constData()));
            if (shapeIdArray == nullptr || shapeID >= shapeIdArray->GetNumberOfValues()) {
                return shapeID;
            }
            shapeID = shapeIdArray->GetValue(vtkCellId);
            break;
        }
        case Exchange::GraphVTKCommons::ShapePickMode::PickMeshCell: {
            if (_meshCellData == nullptr) {
                return shapeID;
            }
            //获取单元可视化数据存储的单元形状id与单元vtkid映射数组
            vtkIntArray* cellIdArray = vtkIntArray::SafeDownCast(
                _meshCellData->GetCellData()->GetArray(GraphVTKCommons::_dataCellIDArratName.toUtf8().constData()));
            if (cellIdArray == nullptr || shapeID >= cellIdArray->GetNumberOfValues()) {
                return shapeID;
            }
            shapeID = cellIdArray->GetValue(vtkCellId);
            break;
        }
        case Exchange::GraphVTKCommons::ShapePickMode::PickMeshVertexSurf: {
            if (_meshFeature == nullptr || _meshFeature->getSurfaceFilter() == nullptr) {
                return -1;
            }
            //获取表面VTK节点id对应的原始VTK节点的id
            int originVTKNodeId = _meshFeature->getSurfaceFilter()->getOriginPointIdBySurfacePointId(vtkCellId);
            //通过原始VTK节点的id获取节点数据id
            shapeID = getShapeIdByVTKCellId(originVTKNodeId, GraphVTKCommons::ShapePickMode::PickMeshVertex);
            break;
        }
        case Exchange::GraphVTKCommons::ShapePickMode::PickMeshCellSurf: {
            if (_meshFeature == nullptr || _meshFeature->getSurfaceFilter() == nullptr) {
                return -1;
            }
            //获取表面VTK单元id对应的原始VTK单元的id
            int originVTKCellId = _meshFeature->getSurfaceFilter()->getOriginCellIdBySurfaceCellId(vtkCellId);
            //通过原始VTK单元的id获取单元数据id
            shapeID = getShapeIdByVTKCellId(originVTKCellId, GraphVTKCommons::ShapePickMode::PickMeshCell);
            break;
        }
        }
        return shapeID;
    }
    int GraphVTKObjectPartMesh::getEleSurfIndexByEleSurfCellID(int vtkCellSurfId, GraphVTKCommons::ShapePickMode pickType)
    {
        switch (pickType)
        {
        case Exchange::GraphVTKCommons::PickMeshCellSurf: {
            int originVTKCellId = -1, surfCellIndex = -1;
            _meshFeature->getSurfaceFilter()->getSurfaceCellInfo(vtkCellSurfId, originVTKCellId, surfCellIndex);
            return surfCellIndex;
            break;
        }
        }
        return -1;
    }
    const QVector<int> GraphVTKObjectPartMesh::getVTKCellIdsByShapeId(int shapeId, GraphVTKCommons::ShapePickMode pickType, QVariant otherInfo)
    {
        QVector<int> vtkIds = {};
        switch (pickType) {
        case Exchange::GraphVTKCommons::ShapePickMode::PickMeshVertex: {
            if (_meshVertexData == nullptr) {
                return vtkIds;
            }
            //获取点可视化数据存储的点形状id与点vtkid映射数组
            vtkIntArray* shapeIdArray = vtkIntArray::SafeDownCast(
                _meshVertexData->GetCellData()->GetArray(GraphVTKCommons::_dataPointIDArratName.toUtf8().constData()));
            if (shapeIdArray == nullptr) {
                return vtkIds;
            }

            for (int vtkId = 0; vtkId < shapeIdArray->GetNumberOfValues(); vtkId++) {
                int saveShapeId = shapeIdArray->GetValue(vtkId);
                if (saveShapeId != shapeId) {
                    continue;
                }
                vtkIds.append(vtkId);
            }
            break;
        }
        case Exchange::GraphVTKCommons::ShapePickMode::PickMeshCell: {
            if (_meshCellData == nullptr) {
                return vtkIds;
            }
            //获取单元可视化数据存储的单元形状id与单元vtkid映射数组
            vtkIntArray* cellIdArray = vtkIntArray::SafeDownCast(
                _meshCellData->GetCellData()->GetArray(GraphVTKCommons::_dataCellIDArratName.toUtf8().constData()));
            if (cellIdArray == nullptr) {
                return vtkIds;
            }
            for (int vtkId = 0; vtkId < cellIdArray->GetNumberOfValues(); vtkId++) {
                int saveShapeId = cellIdArray->GetValue(vtkId);
                if (saveShapeId != shapeId) {
                    continue;
                }
                vtkIds.append(vtkId);
            }
            break;
        }
        case Exchange::GraphVTKCommons::ShapePickMode::PickMeshVertexSurf: {
            if (_meshFeature == nullptr) {
                return vtkIds;
            }
            FITKSurfaceFilter* surFaceFilter = _meshFeature->getSurfaceFilter();
            if (surFaceFilter == nullptr || surFaceFilter->GetOutput() == nullptr) {
                return vtkIds;
            }
            QList<int> pointIndex = otherInfo.value<QList<int>>();
            //通过数据id获取vtkID
            QVector<int> originPointIds = getVTKCellIdsByShapeId(shapeId, Exchange::GraphVTKCommons::ShapePickMode::PickMeshVertex);
            //通过vtkID获取表面vtkID
            for (int originNodeId : originPointIds) {
                int pointNum = surFaceFilter->GetOutput()->GetNumberOfPoints();
                for (int vtkId = 0; vtkId < pointNum; vtkId++) {
                    int saveOriginPointId = surFaceFilter->getOriginPointIdBySurfacePointId(vtkId);
                    if (saveOriginPointId != originNodeId) {
                        continue;
                    }
                    vtkIds.append(vtkId);
                }
            }
            break;
        }
        case Exchange::GraphVTKCommons::ShapePickMode::PickMeshCellSurf: {
            if (_meshFeature == nullptr) {
                return vtkIds;
            }
            FITKSurfaceFilter* surFaceFilter = _meshFeature->getSurfaceFilter();
            if (surFaceFilter == nullptr || surFaceFilter->GetOutput() == nullptr) {
                return vtkIds;
            }
            QList<int> cellIndex = otherInfo.value<QList<int>>();
            //通过数据id获取vtkID
            QVector<int> originCellIds = getVTKCellIdsByShapeId(shapeId, Exchange::GraphVTKCommons::ShapePickMode::PickMeshCell);
            //通过vtkID获取表面vtkID
            for (int originCellId : originCellIds) {
                int cellNum = surFaceFilter->GetOutput()->GetNumberOfCells();
                for (int vtkId = 0; vtkId < cellNum; vtkId++) {
                    int saveOriginCellId = surFaceFilter->getOriginCellIdBySurfaceCellId(vtkId);
                    if (saveOriginCellId != originCellId) {
                        continue;
                    }
                    //获取当前面id的索引
                    int cellIdTemp = -1, indexTemp = -1;
                    surFaceFilter->getSurfaceCellInfo(vtkId, cellIdTemp, indexTemp);
                    Q_UNUSED(cellIdTemp);
                    //判断索引是否在所选参数内
                    if (cellIndex.isEmpty() == false && cellIndex.contains(indexTemp) == false) {
                        continue;;
                    }
                    vtkIds.append(vtkId);
                }
            }
            break;
        }
        }
        return vtkIds;
    }

    bool GraphVTKObjectPartMesh::getVisibility()
    {
        Radioss::FITKRadiossPart* part = dynamic_cast<Radioss::FITKRadiossPart*>(_dataObj);
        if (part == nullptr) {
            return false;
        }

        return this->Superclass::getVisibility();
    }
}
